package org.gruposp2p.proyectokarma.gwt.client.ui;

import org.gruposp2p.proyectokarma.gwt.client.MainEntryPoint;
import org.gruposp2p.proyectokarma.gwt.client.event.EventBusManager;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.Response;
import com.google.gwt.http.client.URL;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import org.gruposp2p.proyectokarma.gwt.client.event.LoginEvent;
import org.gruposp2p.proyectokarma.gwt.client.json.JSONToDomain;
import org.gruposp2p.proyectokarma.gwt.client.ui.user.CreateUserDialog;
import org.gruposp2p.proyectokarma.gwt.client.util.RequestHelper;
import org.gruposp2p.proyectokarma.gwt.client.util.ServerPaths;
import org.gruposp2p.proyectokarma.gwt.client.util.Validator;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.json.client.JSONValue;
import com.allen_sauer.gwt.log.client.Log;

public class LoginDialog {
	
    interface Style extends CssResource {
        String errorTextBox();
        String textBox();
    }
    
    @UiField DialogBox dialogBox;
    @UiField Style style;
    @UiField VerticalPanel mainPanel;
    @UiField VerticalPanel messagePanel;
    @UiField Label messageLabel;
    @UiField Button acceptButton;
    @UiField Button cancelButton;
    @UiField TextBox userTextBox;
    @UiField TextBox passwordTextBox;
    @UiField Anchor recoverPasswordLink;
    @UiField Anchor signUpLink;

    private static LoginDialogUiBinder uiBinder = GWT
                    .create(LoginDialogUiBinder.class);

    interface LoginDialogUiBinder extends
            UiBinder<Widget, LoginDialog> {
    }

    public LoginDialog() {
        uiBinder.createAndBindUi(this);
        messagePanel.setVisible(false);
        acceptButton.setStylePrimaryName("acceptButton");
        cancelButton.setStylePrimaryName("cancelButton");
        SubmitHandler sh = new SubmitHandler();
        userTextBox.addKeyDownHandler(sh);
        passwordTextBox.addKeyDownHandler(sh);
        signUpLink.addClickHandler(signUpLinkHandler);
        recoverPasswordLink.addClickHandler(recoverPasswordLinkHandler);
    }

    public void show() {
        dialogBox.center();
        dialogBox.show();
    }
    
	ClickHandler signUpLinkHandler = new ClickHandler() {
		public void onClick(ClickEvent event) {
			dialogBox.hide();
        	CreateUserDialog createUserDialog = new CreateUserDialog ();
        	createUserDialog.show();
    	}
	};
	
	ClickHandler recoverPasswordLinkHandler = new ClickHandler() {
		public void onClick(ClickEvent event) {
			dialogBox.hide();
			ForgotPasswordDialog forgotPasswordDialog = new ForgotPasswordDialog ();
			forgotPasswordDialog.show();
    	}
	};
	
    @UiHandler("acceptButton")
    void handleAcceptButton(ClickEvent e) {
		if (!isValidForm()) return;
		RequestHelper.submitForm(ServerPaths.getLoginPath(), 
				"j_username=" + URL.encode(userTextBox.getText() + "&j_password=" + URL.encode(passwordTextBox.getText())), 
				new ServerRequestCallback());
		acceptButton.setEnabled(false);
    }
	
    @UiHandler("cancelButton")
    void handleCancelButton(ClickEvent e) {
    	dialogBox.hide();
    }
	
	private boolean isValidForm() {
		if (Validator.isTextBoxEmpty(userTextBox)) {
			setMessage(MainEntryPoint.INSTANCE.constants.emptyFieldException());
			userTextBox.setStyleName(style.errorTextBox(), true);
			return false;
		} else {
			userTextBox.setStyleName(style.errorTextBox(), false);
		}
		if (Validator.isTextBoxEmpty(passwordTextBox)) {
			setMessage(MainEntryPoint.INSTANCE.constants.emptyFieldException());
			passwordTextBox.setStyleName(style.errorTextBox(), true);
			return false;
		} else {
			passwordTextBox.setStyleName(style.errorTextBox(), false);
		}
		return true;
	}
	
	private void setMessage (String message) {
    	messageLabel.setText(message);
    	messagePanel.setVisible(true);
	}
	
    private class ServerRequestCallback implements RequestCallback {

        @Override
    	public void onError(Request request, Throwable exception) {
    		acceptButton.setEnabled(true);
        	new ErrorDialog().show("Exception", exception.getMessage());
        	Log.error(exception.getMessage());
    	}

        @Override
    	public void onResponseReceived(Request request, Response response) {
			Log.debug("StatusCode: " + response.getStatusCode() + 
					", Response Text: " + response.getText()); 
    		if (response.getStatusCode() == Response.SC_OK) {
    			LoginEvent loginEvent = new LoginEvent (LoginEvent.EventType.LOGIN);
                JSONValue jsonValue = JSONParser.parseLenient(response.getText());
    			loginEvent.setPeer(JSONToDomain.getPeer(jsonValue));
                EventBusManager.getInstance().fireEvent(loginEvent);
                dialogBox.hide();
    		} else if (response.getStatusCode() == Response.SC_UNAUTHORIZED) {
            	messageLabel.setText(MainEntryPoint.INSTANCE.constants.loginCredentialsError());
            	messagePanel.setVisible(true);
    		}
    		acceptButton.setEnabled(true);
    	}

    }
    
    private class SubmitHandler implements KeyDownHandler {
		@Override
		public void onKeyDown(KeyDownEvent event) {
			if (KeyCodes.KEY_ENTER == event.getNativeKeyCode()) {
				acceptButton.click();
			}		
		}
	}
    
}